#ifndef XL_UPLOADER_MAIN_WINDOW_H
#define XL_UPLOADER_MAIN_WINDOW_H
#include "../libuploader/libxluploader.h"

#include <atlstr.h>
#include <atltypes.h>
#include <atlbase.h>
#include <atlapp.h>
#include <atlwin.h>
#include <atlctrls.h>
#include <map>
#include <vector>

#include "FileInfo.h"
#include "xDocument.h"
#include "FileListViewCtrl.h"
#include "TransparentStatic.h"
#include "ImagePreviewCtrl.h"
#include "HyperLink.h"


#define WM_APP_UPLOAD_FILE_SUCCESS           (WM_APP + 1) // WPARAM: ID; LPARAM: NOT USED
#define WM_APP_UPLOAD_THREAD_FINISHED        (WM_APP + 2)
#define WM_APP_UPDATE_LISTVIEW               (WM_APP + 3) // WPARAM: ID; LPARAM: NOT USED
#define WM_APP_UPDATE_MAIN_TITLE             (WM_APP + 4) // WPARAM AND LPARAM: NOT USED


typedef CWinTraits<
	WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_THICKFRAME,
	0
	> CMainWindowTraits;

class CMainWindow
	: public CWindowImplBaseT<ATL::CWindow, CMainWindowTraits>
	, public CMessageFilter
	, public CIdleHandler
	, public IFileListViewCtrlParent
	, public CxDocument::IObserver
{
protected:
	CMainWindow(void);
	virtual ~CMainWindow(void);

	static LPCTSTR        m_lpszWindowName;
	static int            m_tabHeight;
	bool                  m_titleUpdated;

	CxDocument            m_document;

	enum _CODE_TYPE {
		CT_URL,
		CT_UBB,
		CT_HTML,
		CT_NUM,
	};


	//////////////////////////////////////////////////////////////////////////
	// children
	enum _IDS {
		ID_CONTROL_BEGIN,
		ID_TAB = ID_CONTROL_BEGIN,
		ID_TABFILES_BEGIN,
			ID_SITE_LIST = ID_TABFILES_BEGIN,
			ID_FILE_LIST,
			ID_PREVIEW,
			ID_MAKE_DONATION,
		ID_TABFILES_END,

 		ID_TABCODE_BEGIN = ID_TABFILES_END,
			ID_STATIC_BEGIN = ID_TABFILES_END,
				ID_STATIC_URL = ID_STATIC_BEGIN,
				ID_STATIC_UBB,
				ID_STATIC_HTML,
			ID_STATIC_END,
			ID_EDIT_BEGIN = ID_STATIC_END,
				ID_EDIT_URL = ID_EDIT_BEGIN,
				ID_EDIT_UBB,
				ID_EDIT_HTML,
			ID_EDIT_END,
			ID_BUTTON_COPY_BEGIN = ID_EDIT_END,
				ID_BUTTON_COPY_URL = ID_BUTTON_COPY_BEGIN,
				ID_BUTTON_COPY_UBB,
				ID_BUTTON_COPY_HTML,
			ID_BUTTON_COPY_END,
 		ID_TABCODE_END = ID_BUTTON_COPY_END,

		ID_BUTTON_BEGIN = ID_TABCODE_END,
			ID_ADD_IMAGE = ID_BUTTON_BEGIN,
			ID_START_UPLOAD,
			ID_STOP_UPLOAD,
			ID_CLEAR_ALL,
			ID_ABOUT,
		ID_BUTTON_END,

		ID_SITE_LINK = ID_BUTTON_END,

		ID_CONTROL_END,

		ID_COMMAND_BEGIN = ID_CONTROL_END,

			ID_CMD_COPY_SELECTED_BEGIN,
				ID_CMD_COPY_SELECTED_URL = ID_CMD_COPY_SELECTED_BEGIN,
				ID_CMD_COPY_SELECTED_UBB,
				ID_CMD_COPY_SELECTED_HTML,
			ID_CMD_COPY_SELECTED_END,
			ID_CMD_REMOVE_SELECTED = ID_CMD_COPY_SELECTED_END,

			// alias cross group must at end
			ID_CMD_CLEAR_ALL = ID_CLEAR_ALL,
		ID_COMMAND_END,
	};
	typedef std::map<_IDS, HWND>	ID2HWND;

	int                     m_fontHeight;
	CTabCtrl                m_tab;
	CFileListViewCtrl       m_fileList;
	CHyperLink              m_hyperMakeDonation;
	CHyperLink              m_hyperSite;
	CComboBox               m_siteSelector;
	CButton                 m_buttons[ID_BUTTON_END - ID_BUTTON_BEGIN];
	CEdit                   m_edits[ID_EDIT_END - ID_EDIT_BEGIN];
	CTransparentStatic      m_statics[ID_STATIC_END - ID_STATIC_BEGIN];
	CButton                 m_copyButtons[ID_BUTTON_COPY_END - ID_BUTTON_COPY_BEGIN];
	CImagePreviewCtrl       m_imageCtrl;

	ID2HWND                 m_id2hwnd;

	tstring _GetCtrlText(_IDS ctrlId);
	CRect _GetChildRect(_IDS id);
	bool _CreateButtons();
	bool _CreateEdits();
	bool _CreateStatics();
	bool _CreateHyperLinks();
	bool _CreateCopyButtons();
	bool _CreateChildren();
	void _LayoutChildren();
	void _UpdateChildren(); // update children status (visibility and etc)
	void _UpdateCode();

	//////////////////////////////////////////////////////////////////////////
	// files
	typedef std::vector<tstring>         FileExtSupported;
	const FileExtSupported& _GetFileExtSupported();
	tstring _GetOpenFileFilter();
	void _DisplayAddFileError(const tstring &failed, const tstring &exists);

	bool _AddFile(const TCHAR *pathname, bool &exists);
	bool _StartUpload();
	bool _StopUpload();

	//////////////////////////////////////////////////////////////////////////
	// UTILS
	static const int MIN_WIDTH = 640;
	static const int MIN_HEIGHT = 480;

	void _OpenContentMenu(const CPoint &pt); // pt in screen
	void _CopyToClipBoard(const tstring &text, bool asHtml = false);
	void _ExportCode(std::stringstream &ss, const std::string &url, _CODE_TYPE ct);
	void _UpdateTitle();


public:
	DECLARE_WND_CLASS_EX(_T("xl::MainWindow"), 0, COLOR_3DFACE)
	typedef CWindowImplBaseT<ATL::CWindow, CMainWindowTraits>	_Base;
	static CMainWindow* getInstance();

	//////////////////////////////////////////////////////////////////////////
	// public methods
	HWND createWindow();
	ISite *getSelectedSite();

	//////////////////////////////////////////////////////////////////////////
	// virtual
	virtual BOOL PreTranslateMessage(MSG* pMsg);
	virtual BOOL OnIdle();
	virtual CRect getFileListViewCtrlRect();
	virtual UINT getFileListViewCtrlId();
	virtual HWND getFileListViewCtrlParentHwnd();
	virtual CxDocument* getDocument();
	virtual void onEvent(EVT evt, void *param);


	BEGIN_MSG_MAP(CMainWindow)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
		MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem)
		MESSAGE_HANDLER(WM_MEASUREITEM, OnMeasureItem)
		MESSAGE_HANDLER(WM_PAINT, OnPaint)
		MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkGnd)
		MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnCtlColorStatic)
		MESSAGE_HANDLER(WM_SIZE, OnSize)
		// MESSAGE_HANDLER(WM_SIZING, OnSize)
		MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
		MESSAGE_HANDLER(WM_GETMINMAXINFO, OnGetMinMaxInfo)
		MESSAGE_HANDLER(WM_DROPFILES, OnDropFiles)

		COMMAND_ID_HANDLER(ID_ADD_IMAGE, OnCmdAddImage)
		COMMAND_ID_HANDLER(ID_START_UPLOAD, OnCmdStartUpload)
		COMMAND_ID_HANDLER(ID_STOP_UPLOAD, OnCmdStopUpload)
		COMMAND_ID_HANDLER(ID_CLEAR_ALL, OnCmdClearAll)
		COMMAND_ID_HANDLER(ID_ABOUT, OnCmdAbout)
		COMMAND_ID_HANDLER(ID_CMD_REMOVE_SELECTED, OnCmdRemoveSelected)
		COMMAND_RANGE_HANDLER(ID_CMD_COPY_SELECTED_BEGIN, (ID_CMD_COPY_SELECTED_END - 1), OnCmdCopySelected)
		COMMAND_RANGE_HANDLER(ID_BUTTON_COPY_BEGIN, (ID_BUTTON_COPY_END - 1), OnCmdCopy)

		MESSAGE_HANDLER(WM_APP_UPLOAD_FILE_SUCCESS, OnUploadFileSuccess)
		MESSAGE_HANDLER(WM_APP_UPLOAD_THREAD_FINISHED, OnUploadThreadFinished)
		MESSAGE_HANDLER(WM_APP_UPDATE_LISTVIEW, OnUpdateListView)
		MESSAGE_HANDLER(WM_APP_UPDATE_MAIN_TITLE, OnUpdateMainTitle)

	END_MSG_MAP()

	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnDrawItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnMeasureItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnEraseBkGnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnCtlColorStatic(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnDropFiles(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

	LRESULT OnCmdAddImage(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
	LRESULT OnCmdStartUpload(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
	LRESULT OnCmdStopUpload(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
	LRESULT OnCmdClearAll(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
	LRESULT OnCmdAbout(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
	LRESULT OnCmdRemoveSelected(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
	LRESULT OnCmdCopy(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
	LRESULT OnCmdCopySelected(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);

	LRESULT OnUploadFileSuccess(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnUploadThreadFinished(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnUpdateListView(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnUpdateMainTitle(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
};

#endif
